package logs

import (
	"fmt"
	"testing"
	"time"
)

// testingLog 使用与testing处理的log
// 不建议使用，因为caller有问题，打印日志对应堆栈位置无法调整
type testingLog struct {
	w     testing.TB
	level LogLevel
	nul   ILog
}

func NewTestingLog(t testing.TB, level LogLevel) *testingLog {
	return &testingLog{
		w:     t,
		level: level,
		nul:   NewNullLog(),
	}
}

func (l testingLog) Debug(format string, params ...interface{}) {
	l.logItem(DebugLog, format, params...)
}
func (l testingLog) Info(format string, params ...interface{}) {
	l.logItem(InfoLog, format, params...)
}
func (l testingLog) Warn(format string, params ...interface{}) {
	l.logItem(WarnLog, format, params...)
}
func (l testingLog) Error(format string, params ...interface{}) {
	l.logItem(ErrorLog, format, params...)
}
func (l testingLog) Panic(format string, params ...interface{}) {
	l.logItem(PanicLog, format, params...)
}
func (l testingLog) Fatal(format string, params ...interface{}) {
	l.logItem(FatalLog, format, params...)
}

func (l testingLog) logItem(level LogLevel, format string, params ...interface{}) {
	if level < LogLevel(l.level) {
		return
	}
	if l.w == nil {
		return
	}
	if len(params) <= 0 {
		s := fmt.Sprintf("[%s]%s: %s\n", level.String(), time.Now().Format(time.RFC3339), format)
		if level >= FatalLog {
			l.w.Fatalf(s)
		} else if level >= ErrorLog {
			l.w.Errorf(s)
		} else {
			l.w.Logf(s)
		}

		return
	}
	l.logItem(level, fmt.Sprintf(format, params...))
}

func (l testingLog) Write(p []byte) (n int, err error) {
	l.w.Logf(string(p))
	return len(p), nil
}

func (l testingLog) Ctl(t bool) ILog {
	if !t {
		return l.nul
	}
	return l
}

func (l testingLog) Caller(offset int) ILog {
	return &testingLog{
		w:     l.w,
		level: l.level,
		nul:   l.nul.CallerSkip(offset),
	}
}

func (l testingLog) CallerSkip(offset int) ILog {
	return l.Caller(offset)
}
